package com.lvhx.springboot.springbatch.base;

import com.lvhx.springboot.base.DefaultUnitOfWorkFactory;
import com.lvhx.springboot.base.TransactionManager;
import com.lvhx.springboot.base.UnitOfWork;
import com.lvhx.springboot.base.UnitOfWorkFactory;
import org.springframework.beans.factory.annotation.Autowired;

public class DefaultActionExecutor implements ActionExecutor {
    private UnitOfWorkFactory unitOfWorkFactory = new DefaultUnitOfWorkFactory();

//    public void setTransactionManager(TransactionManager transactionManager){
//        this.unitOfWorkFactory = new DefaultUnitOfWorkFactory(transactionManager);
//    }

//    @Autowired
//    private DataSourceTransactionManager transactionManager;

    @Autowired
    private TransactionManager transactionManager;
    @Override
    public <T> T excute(ActionCallback action) {
        try {
            return executeInternal(action);
        }catch (Throwable failure){
            if (failure instanceof Error){
                throw (Error)failure;
            }else if (failure instanceof RuntimeException){
                throw (RuntimeException)failure;
            }else {
                throw new RuntimeException("An exception occurred while executing an action",failure);
            }
        }


    }

    private <T> T executeInternal(ActionCallback action) throws Exception{
//         DefaultTransactionDefinition def = new DefaultTransactionDefinition();
//        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
//        TransactionStatus status = transactionManager.getTransaction(def);

        UnitOfWork unitOfWork = unitOfWorkFactory.createUnitOfWork(transactionManager);
        try{
            action.doAction();
        }catch (Throwable throwable){
//            transactionManager.rollback(status);
            unitOfWork.rollback(throwable);
            throw throwable;
        }
//        transactionManager.commit(status);
        unitOfWork.commit();
        return null;
    }

}
